# -*- encoding: utf-8 -*-
'''
file       :decode_shoot_pic.py
Description:从实验环境中拍摄好图像之后把图像切分为3个块, 并与原始图像进行对比
Date       :2022/12/06 11:09:23
Author     :Josco
version    :python3.7.8
'''
from config import *
from public import *



class decode_shoot_pic(object):
    def __init__(self) -> None:
        pass

    def do_decode(self, all_dynamics_point_matrix, shoot_pic, ori_pic):
        """
        desc: 获取所得的动态点位矩阵，并开始三块的解码工作
        param:
            all_dynamics_point_matrix: 所有块的动态点位矩阵list
            shoot_pic: 测试所使用的图片
            ori_pic: 测试所使用的原始图片
        """
        # 读取拍摄后的相机并截图
        lp = cv.imread(shoot_pic)
        
        # 读取原始图像
        ori_img = cv.imread(ori_pic)
        top_bottom = top_bottom_black + top_bottom_white
        left_right = left_right_black + left_right_white
        ori_img = ori_img[top_bottom*n:-top_bottom*n,
                          left_right*n:-(left_right*n), :]
        # 将原始标准图像进行旋转后得
        ori_img = cv.rotate(ori_img, cv.ROTATE_90_COUNTERCLOCKWISE)

        pic_local = 0
        three_bit_data = ""
        for _dynamics_point_matrix in all_dynamics_point_matrix:
            print("这是该图像第%d个色块的验证结果" % pic_local)
            single_bit_data = self.choose_pic_block(lp, ori_img,
                                  _dynamics_point_matrix, pic_local)
            pic_local += 1
            three_bit_data += single_bit_data
        return three_bit_data

        # pic_local = 0
        # for _r in range(90,100):
        #     for _g in range(150,180):
        #         for _b in range(150,180):
        #             self.choose_pic_block_2(lp, ori_img,
        #                                     all_dynamics_point_matrix[pic_local], pic_local, _r, _g, _b)
        # print()
        # print()
        # print()
        # print()
        # return ""

    def choose_pic_block(self, pic_img, ori_img, dynamics_point_matrix, pic_local, camera = camera_2):
        """
        desc: 根据某块动态点位矩阵验证给定图像的色值错误情况
        param:
            dynamics_point_matrix: pic_local块对应的动态点位矩阵
            pic_img: 测试所使用的图片像素矩阵
            ori_img: 测试所使用的原始图片矩阵
            pic_local: 第几块图像
        """
                
        pic_width = int(height/3) # 因为分为3块，所以是height/3

        if pic_local == 0:
            # 获取
            start_x, stop_x, start_y, stop_y = camera[0]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,:pic_width*n,:]
            _r, _g, _b = fin_color_list[0]
            
        elif pic_local == 1:
            start_x, stop_x, start_y, stop_y = camera[1]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,(pic_width+2*(left_right_black+left_right_white))*n:
                                (pic_width*2+2*(left_right_black+left_right_white))*n,:]
            _r, _g, _b = fin_color_list[1]
        else:
            start_x, stop_x, start_y, stop_y = camera[2]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,(pic_width+2*(left_right_black+left_right_white))*n*2:,:]
            _r, _g, _b = fin_color_list[2]

        # 从原始图像中取一个像素代表一个色块
        ori_b = ori_img_matrix[:, :, 0]  # 得到蓝色通道
        ori_g = ori_img_matrix[:, :, 1]  # 得到绿色通道
        ori_r = ori_img_matrix[:, :, 2]  # 得到红色通道
        ori_b = ori_b[int(n/2)::n, int(n/2)::n]
        ori_g = ori_g[int(n/2)::n, int(n/2)::n]
        ori_r = ori_r[int(n/2)::n, int(n/2)::n]

        # 按rgb通道连接数组，在每个色块提取一个像素点保存为色值矩阵
        ori_img_matrix = np.dstack((ori_b, ori_g, ori_r))
        ori_img_matrix = ori_img_matrix.astype("uint8")

        all_row_col = get_matrix_all_row_col(dynamics_point_matrix, pic_local)

        # 用来存储所有matrix并用于计算均值的矩阵
        sum_matrix = np.zeros((dynamics_point_matrix.shape[0], 3))
        for _row_col in all_row_col:
            final_point_color_matrix = lp3[_row_col[0], _row_col[1]]
            sum_matrix += final_point_color_matrix
        sum_matrix = sum_matrix / len(all_row_col)
        # print(sum_matrix)

        # 转为numpy数组并进行reshape
        sum_matrix = sum_matrix.reshape(
            (-1, pic_width, 3))
        # 使用color_to_num把所得色值矩阵所有点进行0，255映射
        final_sum_matrix = color_to_num(sum_matrix, _r, _g, _b)
        all_sum = ori_img_matrix.shape[1] * ori_img_matrix.shape[0]*3
        # 对验证后的正确率进行计算
        true_false_matrix = final_sum_matrix == ori_img_matrix
        print("根据动态点位后对所有点进行复原后的错误的bit位均数: %d, 错误率为：%s%%" % (np.sum(
            true_false_matrix == False), str(np.sum(true_false_matrix == False)/all_sum*100)))
        
        print(np.where(true_false_matrix == False))
        print(sum_matrix[true_false_matrix == False])

        # final_sum_matrix = final_sum_matrix/255
        # final_sum_matrix = final_sum_matrix.astype("uint8")
        # final_sum_matrix = final_sum_matrix.reshape(-1)
        # final_sum_matrix = final_sum_matrix.astype("str")
        # bit_data = "".join(final_sum_matrix)

        
        bit_data = ""
        # final_sum_matrix = final_sum_matrix.tostring()
        # print(final_data)
        # final_sum_matrix = np.packbits(final_sum_matrix)
        # print(final_sum_matrix.decode())

        return bit_data

    def choose_pic_block_2(self, pic_img, ori_img, dynamics_point_matrix, pic_local, _r, _g, _b, camera = camera_2):
        """
        desc: 根据某块动态点位矩阵验证给定图像的色值错误情况
        param:
            dynamics_point_matrix: pic_local块对应的动态点位矩阵
            pic_img: 测试所使用的图片像素矩阵
            ori_img: 测试所使用的原始图片矩阵
            pic_local: 第几块图像
        """
        pic_width = int(height/3) # 因为分为3块，所以是height/3

        if pic_local == 0:
            # 获取
            start_x, stop_x, start_y, stop_y = camera[0]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,:pic_width*n,:]
            
        elif pic_local == 1:
            start_x, stop_x, start_y, stop_y = camera[1]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,(pic_width+2*(left_right_black+left_right_white))*n:
                                (pic_width*2+2*(left_right_black+left_right_white))*n,:]
        else:
            start_x, stop_x, start_y, stop_y = camera[2]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:,(pic_width+2*(left_right_black+left_right_white))*n*2:,:]

        # 从原始图像中取一个像素代表一个色块
        ori_b = ori_img_matrix[:, :, 0]  # 得到蓝色通道
        ori_g = ori_img_matrix[:, :, 1]  # 得到绿色通道
        ori_r = ori_img_matrix[:, :, 2]  # 得到红色通道
        ori_b = ori_b[int(n/2)::n, int(n/2)::n]
        ori_g = ori_g[int(n/2)::n, int(n/2)::n]
        ori_r = ori_r[int(n/2)::n, int(n/2)::n]

        # 按rgb通道连接数组，在每个色块提取一个像素点保存为色值矩阵
        ori_img_matrix = np.dstack((ori_b, ori_g, ori_r))
        ori_img_matrix = ori_img_matrix.astype("uint8")

        all_row_col = get_matrix_all_row_col(dynamics_point_matrix, pic_local)

        # 用来存储所有matrix并用于计算均值的矩阵
        sum_matrix = np.zeros((dynamics_point_matrix.shape[0], 3))
        for _row_col in all_row_col:
            final_point_color_matrix = lp3[_row_col[0], _row_col[1]]
            sum_matrix += final_point_color_matrix
        # print(sum_matrix)
        sum_matrix = sum_matrix / len(all_row_col)
        # print(sum_matrix)
        # 转为numpy数组并进行reshape
        # print("ori_img_matrix.shape[1]", ori_img_matrix.shape[1])
        sum_matrix = sum_matrix.reshape(
            (-1, ori_img_matrix.shape[1], 3))
        # 使用color_to_num把所得色值矩阵所有点进行0，255映射
        final_sum_matrix = color_to_num(sum_matrix, _r, _g, _b)
        all_sum = ori_img_matrix.shape[1] * ori_img_matrix.shape[0]*3

        # 对验证后的正确率进行计算
        true_false_matrix = final_sum_matrix == ori_img_matrix
        # print("_r, _g, _b", _r, _g, _b)
        # print("根据动态点位后对所有点进行复原后的错误的bit位均数: %d, 错误率为：%s%%" % (np.sum(
        #     true_false_matrix == False), str(np.sum(true_false_matrix == False)/all_sum*100)))
        
        # print(np.where(true_false_matrix == False))
        # print(sum_matrix[true_false_matrix == False])

        # final_sum_matrix = final_sum_matrix/255
        # final_sum_matrix = final_sum_matrix.astype("uint8")
        # final_sum_matrix = final_sum_matrix.reshape((-1,))
        # final_sum_matrix = final_sum_matrix.tostring()
        # # final_sum_matrix = np.packbits(final_sum_matrix)
        # # print(final_sum_matrix.decode())

        if np.sum(true_false_matrix == False) < 1:
            print("_r, _g, _b", _r, _g, _b)
            print("根据动态点位后对所有点进行复原后的错误的bit位均数: %d, 错误率为：%s%%" % (np.sum(
            true_false_matrix == False), str(np.sum(true_false_matrix == False)/all_sum*100)))
        
        bit_data = ""
        return bit_data
